msg_tool\scripts\escude\ops/
hanaou.rs

1use super::super::script::ReadParam;
2use super::base::CustomOps;
3use crate::ext::io::*;
4use anyhow::Result;
5use int_enum::IntEnum;
6use std::collections::HashMap;
7use std::io::Seek;
8
9#[repr(u8)]
10#[derive(Debug, IntEnum)]
11enum HanaouOp {
12    End = 0x22,
13    Jump,
14    Call,
15    AutoPlay,
16    Frame,
17    Text,
18    Clear,
19    Gap,
20    Mes,
21    Tlk,
22    Menu,
23    Select,
24    LsfInit,
25    LsfSet,
26    Cg,
27    Em,
28    Clr,
29    Disp,
30    Path,
31    Trans,
32    BgmPlay,
33    BgmStop,
34    BgmVolume,
35    BgmFx,
36    AmbPlay,
37    AmbStop,
38    AmbVolume,
39    AmbFx,
40    SePlay,
41    SeStop,
42    SeWait,
43    SeVolume,
44    SeFx,
45    VocPlay,
46    VocStop,
47    VocWait,
48    VocVolume,
49    VocFx,
50    Quake,
51    Flash,
52    Filter,
53    Effect,
54    Sync,
55    Wait,
56    Movie,
57    Credit,
58    Event,
59    Scene,
60    Title,
61    Notice,
62    Info,
63    SetPass,
64    IsPass,
65    AutoSave,
66    Place,
67    OpenName,
68    Name,
69    LogNew,
70    LogOut,
71    ElapsedDays,
72    Date,
73    TimeTable,
74    Lesson,
75    LessonExp,
76    QuestAdd,
77    QuestDel,
78    QuestMenu,
79    QuestExp,
80    MasterExp,
81    Battle,
82    Status,
83    Tutorial,
84    SetMaster,
85    GetMaster,
86    SetPlayer,
87    GetPlayer,
88    SetQuest,
89    GetQuest,
90    AddSkill,
91    HasSkill,
92    SetDesk,
93    GetLesson,
94    Impact,
95}
96
97#[derive(Debug)]
98pub struct HanaouOps<T: std::fmt::Debug + std::hash::Hash> {
99    prev_name: Option<T>,
100    menus: HashMap<T, T>,
101    last_select: usize,
102}
103
104impl<T: std::fmt::Debug + std::hash::Hash> HanaouOps<T> {
105    pub fn new() -> Self {
106        Self {
107            prev_name: None,
108            menus: HashMap::new(),
109            last_select: 0,
110        }
111    }
112}
113
114use HanaouOp::*;
115
116impl<T> CustomOps<T> for HanaouOps<T>
117where
118    T: std::fmt::Debug + TryInto<u64> + std::hash::Hash,
119{
120    fn run<'a>(&mut self, vm: &mut super::super::script::VM<'a, T>, op: u8) -> Result<bool>
121    where
122        MemReaderRef<'a>: ReadParam<T>,
123        T: TryInto<u64>
124            + Default
125            + Eq
126            + Ord
127            + Copy
128            + std::fmt::Debug
129            + std::fmt::Display
130            + std::hash::Hash
131            + From<u8>
132            + std::ops::Neg<Output = T>
133            + std::ops::Add<Output = T>
134            + std::ops::Sub<Output = T>
135            + std::ops::Mul<Output = T>
136            + std::ops::Div<Output = T>
137            + std::ops::Rem<Output = T>
138            + std::ops::Not<Output = T>
139            + std::ops::BitAnd<Output = T>
140            + std::ops::BitOr<Output = T>
141            + std::ops::BitXor<Output = T>
142            + std::ops::Shr<Output = T>
143            + std::ops::Shl<Output = T>,
144        anyhow::Error: From<<T as TryInto<u64>>::Error>,
145    {
146        if let Ok(op) = HanaouOp::try_from(op) {
147            match op {
148                End => vm.skip_n_params(1, false),
149                Jump => vm.skip_n_params(1, false),
150                Call => vm.skip_n_params(1, false),
151                AutoPlay => vm.skip_n_params(1, false),
152                Frame => vm.skip_n_params(1, false),
153                Text => vm.skip_n_params(2, false),
154                Clear => vm.skip_n_params(1, false),
155                Gap => vm.skip_n_params(2, false),
156                // Handle concat name
157                Mes => {
158                    let params = vm.read_params(Some(1))?;
159                    let mes = params[0];
160                    vm.mess.insert(mes);
161                    if let Some(name) = self.prev_name.take() {
162                        vm.names.insert(mes, name);
163                    }
164                    Ok(false)
165                }
166                Tlk => {
167                    let params = vm.read_params(None)?;
168                    let name = params
169                        .get(0)
170                        .cloned()
171                        .ok_or(anyhow::anyhow!("Missing name parameter"))?;
172                    self.prev_name = Some(name);
173                    Ok(false)
174                }
175                Menu => {
176                    let params = vm.read_params(Some(3))?;
177                    let id = params[0];
178                    let mes = params[1];
179                    vm.mess.insert(mes);
180                    self.menus.insert(id, mes);
181                    Ok(false)
182                }
183                Select => {
184                    let param = vm.read_params(Some(1))?;
185                    println!("Select param: {:?}", param);
186                    if let Some(var) = vm.vars.get_mut(&T::from(131)) {
187                        *var = *var + T::from(1);
188                        return Ok(false);
189                    }
190                    let offset = vm.reader.stream_position()? - 1;
191                    for _ in self.last_select + 1..self.menus.len() {
192                        vm.stack.push(offset);
193                        // println!("Pushing offset: {offset:#x} to stack");
194                    }
195                    vm.vars.insert(T::from(131), T::from(0));
196                    Ok(false)
197                }
198                LsfInit => vm.skip_n_params(1, false),
199                LsfSet => vm.skip_params(false),
200                Cg => vm.skip_params(false),
201                Em => vm.skip_n_params(5, false),
202                Clr => vm.skip_n_params(1, false),
203                Disp => vm.skip_n_params(3, false),
204                Path => vm.skip_params(false),
205                Trans => Ok(false),
206                BgmPlay => vm.skip_n_params(3, false),
207                BgmStop => vm.skip_n_params(1, false),
208                BgmVolume => vm.skip_n_params(2, false),
209                BgmFx => vm.skip_n_params(1, false),
210                AmbPlay => vm.skip_n_params(3, false),
211                AmbStop => vm.skip_n_params(1, false),
212                AmbVolume => vm.skip_n_params(2, false),
213                AmbFx => vm.skip_n_params(1, false),
214                SePlay => vm.skip_n_params(5, false),
215                SeStop => vm.skip_n_params(2, false),
216                SeWait => vm.skip_n_params(1, false),
217                SeVolume => vm.skip_n_params(3, false),
218                SeFx => vm.skip_n_params(1, false),
219                VocPlay => vm.skip_n_params(4, false),
220                VocStop => vm.skip_n_params(2, false),
221                VocWait => vm.skip_n_params(1, false),
222                VocVolume => vm.skip_n_params(3, false),
223                VocFx => vm.skip_n_params(1, false),
224                Quake => vm.skip_n_params(4, false),
225                Flash => vm.skip_n_params(2, false),
226                Filter => vm.skip_n_params(2, false),
227                Effect => vm.skip_n_params(1, false),
228                Sync => vm.skip_n_params(2, false),
229                Wait => vm.skip_n_params(1, false),
230                Movie => vm.skip_n_params(1, false),
231                Credit => vm.skip_n_params(1, false),
232                Event => vm.skip_n_params(1, false),
233                Scene => vm.skip_n_params(1, false),
234                Title => {
235                    let title = vm.read_params(Some(1))?;
236                    vm.mess.insert(title[0]);
237                    Ok(false)
238                }
239                Notice => {
240                    let notices = vm.read_params(Some(3))?;
241                    vm.mess.insert(notices[0]);
242                    Ok(false)
243                }
244                Info => {
245                    let infos = vm.read_params(Some(2))?;
246                    vm.mess.insert(infos[0]);
247                    Ok(false)
248                }
249                SetPass => vm.skip_n_params(2, false),
250                IsPass => vm.skip_n_params(1, false),
251                AutoSave => Ok(false),
252                Place => vm.skip_n_params(1, false),
253                OpenName => vm.skip_n_params(1, false),
254                Name => {
255                    let params = vm.read_params(Some(2))?;
256                    let name = params[0];
257                    let mes = params[1];
258                    vm.mess.insert(mes);
259                    vm.names.insert(mes, name);
260                    Ok(false)
261                }
262                LogNew => vm.skip_n_params(1, false),
263                LogOut => vm.skip_params(false),
264                ElapsedDays => vm.skip_n_params(1, false),
265                Date => Ok(false),
266                TimeTable => vm.skip_n_params(2, false),
267                Lesson => vm.skip_n_params(1, false),
268                LessonExp => vm.skip_n_params(2, false),
269                QuestAdd => vm.skip_n_params(1, false),
270                QuestDel => vm.skip_n_params(1, false),
271                QuestMenu => Ok(false),
272                QuestExp => vm.skip_n_params(2, false),
273                MasterExp => vm.skip_n_params(2, false),
274                Battle => vm.skip_n_params(3, false),
275                Status => Ok(false),
276                Tutorial => vm.skip_n_params(1, false),
277                SetMaster => vm.skip_n_params(3, false),
278                GetMaster => vm.skip_n_params(2, false),
279                SetPlayer => vm.skip_n_params(2, false),
280                GetPlayer => vm.skip_n_params(1, false),
281                SetQuest => vm.skip_n_params(3, false),
282                GetQuest => vm.skip_n_params(2, false),
283                AddSkill => vm.skip_n_params(2, false),
284                HasSkill => vm.skip_n_params(1, false),
285                SetDesk => vm.skip_n_params(2, false),
286                GetLesson => vm.skip_n_params(3, false),
287                Impact => Ok(false),
288            }
289        } else {
290            // return Err(anyhow::anyhow!("Unknown Panicon operation: {op:#02x}"));
291            Ok(false)
292        }
293    }
294}